package kateba.bluetooth;

import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Set;
import java.util.UUID;

import android.app.Activity;
import android.app.ProgressDialog;
import android.bluetooth.BluetoothAdapter;
import android.bluetooth.BluetoothDevice;
import android.bluetooth.BluetoothServerSocket;
import android.bluetooth.BluetoothSocket;
import android.content.Intent;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.util.Log;
import android.view.View;
import android.view.Window;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.Toast;

public class Main extends Activity implements Runnable {
	protected static final String TAG = "TAG";
	private static final int REQUEST_CONNECT_DEVICE = 1;
	private static final int REQUEST_ENABLE_BT = 2;
	Button mScan;
	BluetoothAdapter mBluetoothAdapter;
	private UUID applicationUUID = UUID
	//00001101-0000-1000-8000-00805F9B34FB
//	1101-0000-1000-8000-00805F9B34FB
			.fromString("1101-0000-1000-8000-00805F9B34FB");
	private ProgressDialog mBluetoothConnectProgressDialog;
	private BluetoothSocket mBluetoothSocket;
	BluetoothDevice mBluetoothDevice;
	final String bluetoothName = "bluetoothserver";

	@Override
	public void onCreate(Bundle mSavedInstanceState) {
		super.onCreate(mSavedInstanceState);
		requestWindowFeature(Window.FEATURE_NO_TITLE);
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_FULLSCREEN,
				WindowManager.LayoutParams.FLAG_FULLSCREEN);
		setContentView(R.layout.main);
		mScan = (Button) findViewById(R.id.Scan);

		mScan.setOnClickListener(new View.OnClickListener() {
			public void onClick(View mView) {
				mBluetoothAdapter = BluetoothAdapter.getDefaultAdapter();
				if (mBluetoothAdapter == null) {
					Toast.makeText(Main.this, "Message1", 2000).show();
				} else {
					if (!mBluetoothAdapter.isEnabled()) {
						Intent enableBtIntent = new Intent(
								BluetoothAdapter.ACTION_REQUEST_ENABLE);
						startActivityForResult(enableBtIntent,
								REQUEST_ENABLE_BT);
					} else {
						// // here i will start server to listen for connection
						// no need to list all paired device

						// startServer();

						ListPairedDevices();
						Intent connectIntent = new Intent(Main.this,
								DeviceListActivity.class);
						startActivityForResult(connectIntent,
								REQUEST_CONNECT_DEVICE);
//						startServer();
					}
				}
			}
		});

	}// onCreate

	public void onActivityResult(int mRequestCode, int mResultCode,
			Intent mDataIntent) {
		super.onActivityResult(mRequestCode, mResultCode, mDataIntent);

		switch (mRequestCode) {
		case REQUEST_CONNECT_DEVICE:
			// TODO:connect device
			if (mResultCode == Activity.RESULT_OK) {
				Bundle mExtra = mDataIntent.getExtras();
				String mDeviceAddress = mExtra.getString("DeviceAddress");
				Log.v(TAG, "Coming incoming address " + mDeviceAddress);
				mBluetoothDevice = mBluetoothAdapter
						.getRemoteDevice(mDeviceAddress);
				mBluetoothConnectProgressDialog = ProgressDialog.show(this,
						"Connecting...", mBluetoothDevice.getName() + " : "
								+ mBluetoothDevice.getAddress(), true, false);
				Thread mBlutoothConnectThread = new Thread(this);
				 mBlutoothConnectThread.start();
				// pairToDevice(mBluetoothDevice); This method is replaced by
				// progress dialog with thread
			}
			break;

		case REQUEST_ENABLE_BT:
			if (mResultCode == Activity.RESULT_OK) {
				ListPairedDevices();
				Intent connectIntent = new Intent(Main.this,
						DeviceListActivity.class);
				startActivityForResult(connectIntent, REQUEST_CONNECT_DEVICE);
			} else {
				Toast.makeText(Main.this, "Message", 2000).show();
			}
			break;
		}
	}

	private void ListPairedDevices() {
		Set<BluetoothDevice> mPairedDevices = mBluetoothAdapter
				.getBondedDevices();
		if (mPairedDevices.size() > 0) {
			for (BluetoothDevice mDevice : mPairedDevices) {
				Log.v(TAG, "PairedDevices: " + mDevice.getName() + " "
						+ mDevice.getAddress());
			}
		}
	}

	public void run() {
		try {

			mBluetoothSocket = mBluetoothDevice
					.createRfcommSocketToServiceRecord(applicationUUID);
			mBluetoothAdapter.cancelDiscovery();
			Log.i("Salama","mBluetoothAdapter.cancelDiscovery();");

		//	mBluetoothSocket.connect();
			Log.i("Salama","mBluetoothSocket.connect()");
			ConnectedThread connectedThread=new ConnectedThread(mBluetoothSocket);
			connectedThread.start();
			Log.i("Salama","after mBluetoothSocket.connect()");
			if (mHandler.sendEmptyMessage(0)) {
				Log.i("salama", "True");
//				ConnectedThread connectedThread=new ConnectedThread(mBluetoothSocket);
//				connectedThread.start();
			} else {
				Log.i("salama", "false");
			}

		} catch (IOException eConnectException) {
//			eConnectException.printStackTrace();
			Log.d(TAG, "CouldNotConnectToSocket", eConnectException);
			closeSocket(mBluetoothSocket);
			unregisterReceiver(DeviceListActivity.getBroadcastReceiver());
			return;
		}
	}

	private void closeSocket(BluetoothSocket nOpenSocket) {
		try {
			nOpenSocket.close();
			Log.d(TAG, "SocketClosed");
		} catch (IOException ex) {
			Log.d(TAG, "CouldNotCloseSocket");
		}
	}

	private Handler mHandler = new Handler() {
		@Override
		public void handleMessage(Message msg) {
			mBluetoothConnectProgressDialog.dismiss();
			Toast.makeText(Main.this, "DeviceConnected", 5000).show();
		}
	};

	public void startServer() {

		Thread acceptThread = new Thread(new Runnable() {
			public void run() {
				try {
					BluetoothServerSocket server = mBluetoothAdapter
							.listenUsingRfcommWithServiceRecord(bluetoothName,
									applicationUUID);
					
					BluetoothSocket serverSocket = server.accept();

					DataInputStream dataInput = new DataInputStream(
							serverSocket.getInputStream());
					DataOutputStream dataOut = new DataOutputStream(
							serverSocket.getOutputStream());
					// try to read and write double
					int recieved = dataInput.readInt();
					// dataOut.writeDouble(12);
					char c = dataInput.readChar();
					Log.i("BLUETOOTH", "recieved from client is " + recieved);
					Log.i("BLUETOOTH", "recieved from client is " + c);
				} catch (IOException e) {
					Log.i("BLUETOOTH", e.getMessage());
				}
			}
		});
		acceptThread.start();

	}


//	private class ConnectThread extends Thread {
//	    private final BluetoothSocket mmSocket;
//	    private final BluetoothDevice mmDevice;
//	 
//	    public ConnectThread(BluetoothDevice device) {
//	        // Use a temporary object that is later assigned to mmSocket,
//	        // because mmSocket is final
//	        BluetoothSocket tmp = null;
//	        mmDevice = device;
//	 
//	        // Get a BluetoothSocket to connect with the given BluetoothDevice
//	        try {
//	            // MY_UUID is the app's UUID string, also used by the server code
//	            tmp = device.createRfcommSocketToServiceRecord(applicationUUID);
//	        } catch (IOException e) { }
//	        mmSocket = tmp;
//	    }
//	 
//	    public void run() {
//	        // Cancel discovery because it will slow down the connection
//	        mBluetoothAdapter.cancelDiscovery();
//	 
//	        try {
//	            // Connect the device through the socket. This will block
//	            // until it succeeds or throws an exception
//	            mmSocket.connect();
//	        } catch (IOException connectException) {
//	            // Unable to connect; close the socket and get out
//	            try {
//	                mmSocket.close();
//	            } catch (IOException closeException) { }
//	            return;
//	        }
//	 
//	        // Do work to manage the connection (in a separate thread)
//	        manageConnectedSocket(mmSocket);
//	    }
//	 
//	    private void manageConnectedSocket(BluetoothSocket mmSocket2) {
//			// TODO Auto-generated method stub
//			ConnectedThread connectedThread=new ConnectedThread(mmSocket2);
//			connectedThread.start();
//		}
//	    
//
//		/** Will cancel an in-progress connection, and close the socket */
//	    public void cancel() {
//	        try {
//	            mmSocket.close();
//	        } catch (IOException e) { }
//	    }
//	}
//	
	private class ConnectedThread extends Thread {
	    private final BluetoothSocket mmSocket;
	    private final InputStream mmInStream;
	    private final OutputStream mmOutStream;
	 
	    public ConnectedThread(BluetoothSocket socket) {
	        mmSocket = socket;
	        InputStream tmpIn = null;
	        OutputStream tmpOut = null;
	 
	        // Get the input and output streams, using temp objects because
	        // member streams are final
	        try {
	        	Log.i("################################",""+socket.getRemoteDevice().getAddress());
	        	Log.i("################################",""+socket.getRemoteDevice().getName());
	        	socket.connect();
	            tmpIn = socket.getInputStream();
	            tmpOut = socket.getOutputStream();
	        } catch (IOException e) { 
	        	try {
					socket.close();
				} catch (IOException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
	        	Log.i("Salama","IOException");
	        	e.printStackTrace();
	        	
	        	
	        }
	 
	        mmInStream = tmpIn;
	        mmOutStream = tmpOut;
	    }
	 
	    public void run() {
	        byte[] buffer = new byte[1024];  // buffer store for the stream
	        int bytes; // bytes returned from read()
	 
	        // Keep listening to the InputStream until an exception occurs
	        while (true) {
	            try {
	                // Read from the InputStream
	                bytes = mmInStream.read(buffer);
Log.i("####Salama#####",bytes+"");

	                // Send the obtained bytes to the UI activity
	                mHandler.obtainMessage(1, bytes, -1, buffer)
	                        .sendToTarget();
	            } catch (IOException e) {
	            cancel();
	            Log.i("Salama","IOException--------------------------------------------------------------");
	            	break;
	            }
	        }
	    }
	 
	    /* Call this from the main activity to send data to the remote device */
//	    public void write(byte[] bytes) {
//	        try {
//	            mmOutStream.write(bytes);
//	        } catch (IOException e) { }
//	    }
	 
	    /* Call this from the main activity to shutdown the connection */
	    public void cancel() {
	        try {
	            mmSocket.close();
	        } catch (IOException e) { }
	    }
	}
}
